package collection;

import jdk.nashorn.internal.runtime.arrays.ArrayIndex;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 集合的遍历
 * 集合提供了同一的遍历方式:迭代器.
 * Iterator iterator()
 * 该方法会返回一个同于遍历当前集合元素的迭代器.
 * java.util.Iterator接口是迭代器接口，规定了遍历集合的相关操作，不同的集合都提供了用于遍历
 * 自身元素的迭代器实现类。
 * 迭代器遍历集合遵循的步骤为:1.问,2.取,3.删.其中删除操作不是必须操作.
 *
 * JDK5推出时，推出了一个新的特性:  泛型   <E>:指定类型,编译器认可.
 * 泛型也称参数化类型，使得我们在使用一个类时可以指定其内部某个属性，方法参数或返回值的类型。
 * 这样使用这个类可以更灵活。
 * 泛型在集合中被广泛使用，用于定义集合中的元素类型。
 * 泛型是编译器认可的，泛型的原型是Object，指定泛型的类型可以让编译器辅助一下操作：
 * 赋值时，编译器会检查给定的值是否符合泛型指定的类型，不符合则编译不通过。
 * 获取值时，编译器会自动补充造型代码，转换为泛型指定的类型.
 * 泛型:1.:支持引用类型; 2.:不支持基本类型,可以写相应的包装类;例如:int -> Integer
 */
public class IteratorDemo1 {
    public static void main(String[] args) {
        //Collection<E>声明是E用于在集合中指定元素.
        Collection<String> c = new ArrayList<>();//指定泛型实际类型为String
        /*
            boolean add(E e)
            编译器会将E当成String来检验调用该方法时实际传入的参数类型.
            泛型:1.:支持引用类型; 2.:不支持基本类型,可以写相应的包装类;例如:int -> Integer
         */
        c.add("one");//检查参数类型是否为String
//        c.add(123);//编译不通过,实参类型不是String
        c.add("#");
        c.add("two");
        c.add("#");
        c.add("three");
        c.add("#");
        c.add("四");
        c.add("#");
        c.add("5");
        System.out.println(c);
        /** Iterator iterator() 迭代器. */
        /*7
            boolean hasNext()
            判断集合是否还有下一个元素可以遍历。第一次调用时就是判断是否有第一个元素，以此类推.

            E next()
            使迭代器获取下一个元素。第一次调用时就是获取第一个元素.

            注:迭代器默认是在集合第一个元素之前的位置.
         */
        //迭代器也支持泛型，指定时与其遍历的集合指定的泛型一致即可.
        Iterator<String> len = c.iterator();
        while (len.hasNext()){//问
            /*
                迭代器指定泛型后，next方法获取元素时不需要在造型(编译器编译成Class文件时,会补充造型代码)
             */
            String str =len.next();//取
            System.out.println(str);
            if("#".equals(str)){
                /*
                    使用迭代器遍历集合的过程中不要通过集合的方法增删元素集合否则会出现异常.
                    ConcurrentModificationException
                 */
//                c.remove(str);
                /*
                    迭代器提供了remove方法，删除的是本次通过next方法获取的元素.
                 */
                len.remove();
            }
        }
        System.out.println(c);
    }
}
